from django.contrib import admin
from django.contrib.admin import ModelAdmin
from django.contrib.auth.models import Group
from django.http import JsonResponse
from django.urls import path, reverse
from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django.views.decorators.csrf import csrf_exempt

from tickets.audit import AuditLogger
from tickets.models import Ticket, ApprovalProcess, ApprovalStep, ApprovalRecord

# 更改管理后台名称
admin.site.site_header = '现代金控运维工单系统'

class GroupPermissionHandler:
    def __init__(self, request):
        self.user = request.user
        self.groups = self.user.groups.values_list('name', flat=True)

    def is_superuser(self):
        return self.user.is_superuser

    def get_queryset(self, qs):
        """
        控制获取的数据
        """
        if self.is_superuser():
            return qs
        if '研发组' in self.groups:
            return qs.filter(created_by=self.user)
        if '研发管理组' in self.groups:
            return qs.filter(status__in=['submitted', 'level1_approved', 'rejected', 'completed'])
        if '技术中心管理组' in self.groups:
            return qs.filter(status__in=['level1_approved', 'level2_approved','rejected', 'completed'])
        if '运维管理组' in self.groups:
            return qs.filter(status__in=['level2_approved','rejected', 'final_approved'])
        if '系统组' in self.groups:
            return qs.filter(ticket_type='system').exclude(status='pending')
        if '数据组' in self.groups:
            return qs.filter(ticket_type='database').exclude(status='pending')
        return qs.none()

    def get_fields(self, obj=None):
        """
        详情页
        """
        if self.is_superuser():
            return ['title', 'ticket_type', 'description', 'attachment', 'status', 'executor', 'remark', 'created_by', 'approval_process']
        if '研发组' in self.groups:
            return ['title', 'ticket_type', 'description', 'attachment', 'status']
        if '研发管理组' in self.groups:
            return ['title', 'description', 'created_by','status','operate']
        if '技术中心管理组' in self.groups:
            return ['title', 'description', 'created_by','status', 'remark', 'approval_process']
        if '运维管理组' in self.groups:
            return ['title', 'description', 'created_by','status', 'remark', 'approval_process']
        if '系统组' in self.groups:
            return ['title', 'description', 'created_by', 'status', 'remark']
        if '数据组' in self.groups:
            return ['title', 'description', 'created_by','status','remark']
        return []

    def get_readonly_fields(self, obj=None):
        """
        返回只读字段
        """
        if self.is_superuser():
            return []
        if '研发组' in self.groups:
            return ['status','executor', 'approval_process', 'created_by', 'created_at', 'updated_at']
        if '研发管理组' in self.groups:
            return ['status', 'executor', 'created_by', 'created_at', 'updated_at']
        if '技术中心管理组' in self.groups:
            return ['status','executor', 'created_by', 'created_at', 'updated_at']
        if '运维管理组' in self.groups:
            return ['status','executor', 'created_by', 'created_at', 'updated_at']
        return ['created_by', 'created_at', 'updated_at']

    def can_change(self, obj=None):
        """
        控制编辑权限
        """
        # 超级管理员无限制
        if self.is_superuser():
            return True

        # 研发只能编辑没有提交的
        if obj and obj.status not in ['pending'] and '研发组' in self.groups:
            return False

        if obj and obj.status == 'pending':
            return True

        return False

    def can_delete(self):
        """
        控制删除权限
        """
        return self.is_superuser()

    def get_status_choices(self):
        """
        限制状态字段的选项
        """
        if self.is_superuser():
            return None
        if '研发组' in self.groups:
            return [
                ('pending', '未提交'),
                ('submitted', '待审批'),
            ]
        if '研发管理组' in self.groups:
            return [
                ('submitted', '待审批'),
                ('level1_approved', '一级审批已通过'),
                ('rejected', '一级审批未通过'),
            ]
        if '技术中心管理组' in self.groups:
            return [
                ('level1_approved', '待审批'),
                ('level2_approved', '二级审批已通过'),
                ('rejected', '二级审批未通过'),
            ]
        if '运维管理组' in self.groups:
            return [
                ('level2_approved', '待审批'),
                ('final_approved', '最终审批已通过'),
                ('rejected', '最终审批未通过'),
            ]
        return None


@admin.register(Ticket)
class TicketAdmin(admin.ModelAdmin):
    list_filter = ('ticket_type', 'status', 'created_at')
    search_fields = ('title', 'description')
    ordering = ('-created_at',)

    # 列表页面
    def get_list_display(self, request):
        default_list_display = ('title', 'ticket_type', 'colored_status', 'created_by', 'executor', 'created_at', 'updated_at')

        # 如果用户是超级管理员，显示管理员的字段列表
        if request.user.is_superuser:
            list_display = ('title', 'ticket_type', 'colored_status', 'created_by', 'executor', 'created_at', 'updated_at')
            return list_display

        # 检查用户组，调整展示字段
        if request.user.groups.filter(name='研发组').exists():
            list_display = (
            'title', 'ticket_type', 'colored_status', 'created_by', 'executor', 'created_at', 'updated_at', 'operate')
            return list_display
        elif request.user.groups.filter(name__icontains='管理').exists():
            list_display = ('title', 'ticket_type', 'colored_status', 'created_by', 'executor', 'created_at', 'updated_at', 'operate')
            return list_display

        if request.user.groups.filter(name='系统组').exists():
            list_display = ('title', 'ticket_type', 'colored_status', 'created_by', 'executor', 'created_at', 'updated_at', 'operate')
            return list_display
        if request.user.groups.filter(name='数据组').exists():
            list_display = ('title', 'ticket_type', 'colored_status', 'created_by', 'executor', 'created_at', 'updated_at', 'operate')
            return list_display

        # 默认返回的字段列表
        return default_list_display

    # 自定义带颜色的状态显示
    @admin.display(description='状态')
    def colored_status(self, obj):
        color = 'black'  # 默认黑色
        if obj.status == 'level1_approved':
            color = 'green'
        elif obj.status == 'level2_approved':
            color = 'green'
        elif obj.status == 'level3_approved':
            color = 'green'
        elif obj.status == 'final_approved':
            color = 'green'
        elif obj.status == 'rejected':
            color = 'red'
        elif obj.status == 'submitted':
            color = 'black'

        return format_html(
            f'<span style="color: {color}; font-weight: bold;">{obj.get_status_display()}</span>')

    @admin.display(description='操作', ordering='name')
    def operate(self, obj):
        # 动态按钮生成
        approve_url = reverse('admin:ticket_approve', args=[obj.id])
        reject_url = reverse('admin:ticket_reject', args=[obj.id])
        submit_url = reverse('admin:ticket_submit', args=[obj.id])
        btn1 = f"""<button onclick="fetch('{approve_url}', {{method: 'POST'}}).then(() => location.reload())"
                       class="el-button el-button--success el-button--small">通过</button>"""
        btn2 = f"""<button onclick="fetch('{reject_url}', {{method: 'POST'}}).then(() => location.reload())"
                       class="el-button el-button--danger el-button--small">拒绝</button>"""
        btn3 = f"""<button onclick="fetch('{submit_url}', {{method: 'POST'}}).then(() => location.reload())"
                       class="el-button el-button--danger el-button--small">提交</button>"""

        user_groups = [group.name for group in self.request.user.groups.all()]

        if '研发管理组' in user_groups:
            if obj.status in ['level1_approved', 'rejected']:
                return ''
        if '技术中心管理组' in user_groups:
            if obj.status in ['level2_approved', 'rejected']:
                return ''
        if '运维管理组' in user_groups:
            if obj.status in ['final_approved', 'rejected']:
                return ''
        if '数据组' in user_groups or '系统组' in user_groups:
            if obj.status in ['final_approved']:
                return mark_safe(f"<div>{btn1}{btn2}</div>")
            else:
                return ''
        if '研发组' in user_groups:
            if obj.status in ['pending']:
                return mark_safe(f"<div>{btn3}</div>")
        else:
            return mark_safe(f"<div>{btn1}{btn2}</div>")




    # 注册自定义 URL
    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path('approve/<int:ticket_id>/', self.admin_site.admin_view(self.approve_ticket), name='ticket_approve'),
            path('reject/<int:ticket_id>/', self.admin_site.admin_view(self.reject_ticket), name='ticket_reject'),
            path('submit/<int:ticket_id>/', self.admin_site.admin_view(self.submit_ticket), name='ticket_submit'),
        ]
        return custom_urls + urls

    @csrf_exempt
    def approve_ticket(self, request, ticket_id):
        """
                自定义视图：审批工单
                """
        try:
            ticket = Ticket.objects.get(id=ticket_id)
            user_groups = [group.name for group in request.user.groups.all()]
            comments = None
            # 检查当前用户是否属于当前审批组
            if ticket.current_group and ticket.current_group.name not in user_groups:
                return JsonResponse({'success': False, 'message': '您没有权限审批此工单'}, status=403)
            if '研发管理组' in user_groups:
                ticket.status = 'level1_approved'
                comments = f'研发管理组 {request.user} 通过审批'
            elif '技术中心管理组' in user_groups:
                ticket.status = 'level2_approved'
                comments = f'技术中心管理组 {request.user} 通过审批'
            elif '运维管理组' in user_groups:
                ticket.status = 'final_approved'
                comments = f'运维管理组 {request.user} 通过审批'
            elif '系统组' in user_groups or '数据组' in user_groups:
                ticket.status = 'completed'
                comments = f'{request.user} 完成了工单'
            else:
                return JsonResponse({'success': False, 'message': '用户组权限不足'}, status=403)

            # 保存工单状态
            ticket.save()

            # 记录审批日志
            step = ApprovalStep.objects.get(ticket=ticket)

            AuditLogger.log_approval(ticket, step, Group.objects.get(name=user_groups[0]), request.user, ticket.status,
                                     comments)
            return JsonResponse({'success': True})
        except Ticket.DoesNotExist:
            return JsonResponse({'success': False, 'message': '工单不存在'}, status=404)
        except ApprovalStep.DoesNotExist:
            return JsonResponse({'success': False, 'message': '审批步骤不存在'}, status=404)
        except Exception as e:
            return JsonResponse({'success': False, 'message': f'服务器错误: {str(e)}'}, status=500)

    # 自定义视图：拒绝工单
    @csrf_exempt
    def reject_ticket(self, request, ticket_id):
        """
                自定义视图：拒绝工单
                """
        try:
            ticket = Ticket.objects.get(id=ticket_id)
            user_groups = [group.name for group in request.user.groups.all()]

            if '研发管理组' in user_groups:
                ticket.status = 'level1_rejected'
                comments = f'研发管理组 {request.user} 未通过审批'
            elif '技术中心管理组' in user_groups:
                ticket.status = 'level2_rejected'
                comments = f'技术中心管理组 {request.user} 未通过审批'
            elif '运维管理组' in user_groups:
                ticket.status = 'final_rejected'
                comments = f'运维管理组 {request.user} 未通过审批'
            elif '系统组' in user_groups or '数据组' in user_groups:
                ticket.status = 'rejected'
                comments = f'{request.user} 驳回了工单'
            else:
                return JsonResponse({'success': False, 'message': '用户组权限不足'}, status=403)

            ticket.save()


            return JsonResponse({'success': True})
        except Ticket.DoesNotExist:
            return JsonResponse({'success': False, 'message': '工单不存在'}, status=404)
        except ApprovalStep.DoesNotExist:
            return JsonResponse({'success': False, 'message': '审批步骤不存在'}, status=404)
        except Exception as e:
            return JsonResponse({'success': False, 'message': f'服务器错误: {str(e)}'}, status=500)


    @csrf_exempt
    def submit_ticket(self, request, ticket_id):
        """
                自定义视图：提交工单
                """
        try:
            ticket = Ticket.objects.get(id=ticket_id)

            # 更新工单状态
            ticket.status = 'submitted'
            ticket.save()

            # 记录提交日志
            step = ApprovalStep.objects.get(ticket=ticket)
            comments = f'{request.user} 提交了工单'
            AuditLogger.log_approval(ticket, step, None, request.user, 'submitted', comments)

            return JsonResponse({'success': True})
        except Ticket.DoesNotExist:
            return JsonResponse({'success': False, 'message': '工单不存在'}, status=404)
        except ApprovalStep.DoesNotExist:
            return JsonResponse({'success': False, 'message': '审批步骤不存在'}, status=404)
        except Exception as e:
            return JsonResponse({'success': False, 'message': f'服务器错误: {str(e)}'}, status=500)

    def get_queryset(self, request):
        """
        根据权限限制用户访问的工单范围
        """
        # 将 request 注入到实例中
        self.request = request
        qs = super().get_queryset(request)
        handler = GroupPermissionHandler(request)
        return handler.get_queryset(qs)

    def get_fields(self, request, obj=None):
        """
        编辑框显示内容
        """
        handler = GroupPermissionHandler(request)
        fields = handler.get_fields(obj)
        return fields if fields else super().get_fields(request, obj)

    def get_readonly_fields(self, request, obj=None):
        """
        根据权限动态设置只读字段
        """
        handler = GroupPermissionHandler(request)
        return handler.get_readonly_fields(obj)

    def has_change_permission(self, request, obj=None):
        """
        根据权限控制编辑权限
        """
        handler = GroupPermissionHandler(request)
        return handler.can_change(obj)

    def has_delete_permission(self, request, obj=None):
        """
        根据权限控制删除权限
        """
        handler = GroupPermissionHandler(request)
        return handler.can_delete()

    def formfield_for_choice_field(self, db_field, request, **kwargs):
        """
        根据权限限制状态字段的选项
        """
        handler = GroupPermissionHandler(request)
        if db_field.name == 'status':
            choices = handler.get_status_choices()
            if choices:
                kwargs['choices'] = choices
        return super().formfield_for_choice_field(db_field, request, **kwargs)

    def save_model(self, request, obj, form, change):
        """
        保存时处理不同权限逻辑
        """

        # 如果是新建对象，设置 created_by 为当前用户
        if not change or not obj.pk:  # 判断是否是新建而非修改
            obj.created_by = request.user

        handler = GroupPermissionHandler(request)
        if handler.get_status_choices() and obj.status not in dict(handler.get_status_choices()):
            raise PermissionError("状态无效或不允许修改")
        super().save_model(request, obj, form, change)

    class Media:
        js = (
            'admin/wangeditor/index.js',
            'admin/wangeditor/user.js',
        )
        css = {
            'all': ('admin/wangeditor/style.css',
                    'admin/wangeditor/user.css',),
        }


@admin.register(ApprovalProcess)
class ApprovalProcessAdmin(ModelAdmin):
    list_display = ('name', 'process_type', 'created_at')
    list_per_page = 50

    def has_view_permission(self, request, obj=None):
        return request.user.has_perm('tickets.can_manage_system_tickets')

    def has_add_permission(self, request):
        return request.user.has_perm('tickets.can_manage_system_tickets')

    def has_change_permission(self, request, obj=None):
        return request.user.has_perm('tickets.can_manage_system_tickets')

    def has_delete_permission(self, request, obj=None):
        return request.user.has_perm('tickets.can_manage_system_tickets')


@admin.register(ApprovalStep)
class ApprovalStepAdmin(ModelAdmin):
    list_display = ('process', 'step_number', 'group')
    list_per_page = 50

    def has_view_permission(self, request, obj=None):
        return request.user.has_perm('tickets.can_manage_system_tickets')

    def has_add_permission(self, request):
        return request.user.has_perm('tickets.can_manage_system_tickets')

    def has_change_permission(self, request, obj=None):
        return request.user.has_perm('tickets.can_manage_system_tickets')

    def has_delete_permission(self, request, obj=None):
        return request.user.has_perm('tickets.can_manage_system_tickets')


@admin.register(ApprovalRecord)
class ApprovalRecordAdmin(ModelAdmin):
    list_display = ('ticket', 'step', 'group', 'approved_by', 'approved_at', 'status', 'comments')
    list_per_page = 50

    def has_view_permission(self, request, obj=None):
        return request.user.has_perm('tickets.can_approve_all_tickets')

    def has_add_permission(self, request):
        return request.user.has_perm('tickets.can_approve_all_tickets')

    def has_change_permission(self, request, obj=None):
        return request.user.has_perm('tickets.can_approve_all_tickets')

    def has_delete_permission(self, request, obj=None):
        return request.user.has_perm('tickets.can_approve_all_tickets')
